/*
 *  Copyright 2008 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.antext.core.generate;

/**
 * Utility class used to transform strings. Note that it's used from Velocity
 * templates, so it's API should be changed carefully.
 * <p><a href="StringTransformer.java.html"><i>View source</i></a></p>
 *
 * @author Roman Puchkovskiy <a href="mailto:roman.puchkovskiy@blandware.com">
 *         &lt;roman.puchkovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.5 $ $Date: 2008/05/13 17:47:31 $
 */
public class StringTransformer {
    /**
     * Turns first character to upper case.
     *
     * @param s     string to capitalize
     * @return capitalized string
     */
    public String capitalize(String s) {
        String result;
        if (s == null || s.length() == 0) {
            result = s;
        } else {
            StringBuffer buf = new StringBuffer();
            buf.append(Character.toUpperCase(s.charAt(0)));
            buf.append(s.substring(1));
            result = buf.toString();
        }
        return result;
    }

    /**
     * Turns first character to lower case.
     *
     * @param s     string to decapitalize
     * @return decapitalized string
     */
    public String decapitalize(String s) {
        String result;
        if (s == null || s.length() == 0) {
            result = s;
        } else {
            StringBuffer buf = new StringBuffer();
            buf.append(Character.toLowerCase(s.charAt(0)));
            buf.append(s.substring(1));
            result = buf.toString();
        }
        return result;
    }

    /**
     * Turns camel-cased phrase to a phrase where words are separated with
     * underscore character. In the resulting string, all characters are
     * lower-case. Example: camelCaseToUnderscoreSeparated("oneTwoThree") gives
     * "one_two_three".
     *
     * @param s         string to process
     * @return processed string
     */
    public String camelCaseToUnderscoreSeparated(String s) {
        return camelCaseToCharSeparated(s, '_');
    }

    /**
     * Turns camel-cased phrase to a phrase where words are separated with
     * space character. In the resulting string, all characters are lower-case.
     * Example: camelCaseToSpaceSeparated("oneTwoThree") gives "one two three".
     *
     * @param s         string to process
     * @return processed string
     */
    public String camelCaseToSpaceSeparated(String s) {
        return camelCaseToCharSeparated(s, ' ');
    }

    /**
     * Turns camel-cased phrase to a phrase where words are separated with a
     * given character. In the resulting string, all characters are lower-case.
     * Example: camelCaseToCharSeparated("oneTwoThree", '-') gives
     * "one-two-three".
     *
     * @param s         string to process
     * @param separator separator character
     * @return processed string
     */
    public String camelCaseToCharSeparated(String s, char separator) {
        StringBuffer buf = new StringBuffer();
        boolean lastWasLower = false;
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            boolean lower = Character.isLowerCase(ch);
            if (ch == separator) {
                // treating separator as a lower-case... because this works
                // for our purposes
                lower = true;
            }
            boolean needUnderscore = i > 0 && lastWasLower && !lower;
            if (needUnderscore) {
                buf.append(separator);
            }
            buf.append(Character.toLowerCase(ch));
            lastWasLower = lower;
        }
        return buf.toString();
    }

    /**
     * Converts a string to a 'plural form'. That is, transforms 'apple' to
     * 'apples', 'map' to 'maps', but 'torch' to 'torches' ('es' instead of
     * 's' is added to strings which end with 's', 'ch', 'sh'), 'copy' to
     * 'copies' (trailing 'y' is replaced with 'ies'). Case is preserved.
     *
     * @param s     string to convert.
     * @return converted string
     */
    public String pluralize(String s) {
        String result = s;
        if (s.endsWith("y")) {
            result = s.substring(0, s.length() - 1) + "ies";
        } else if (s.endsWith("Y")) {
            result = s.substring(0, s.length() - 1) + "IES";
        } else if (s.endsWith("s") || s.endsWith("ch") || s.endsWith("sh")) {
            result = s + "es";
        } else if (s.endsWith("S") || s.endsWith("CH") || s.endsWith("SH")) {
            result = s + "ES";
        } else {
            result = s + "s";
        }
        return result;
    }
}
